package com.victualler.core.common.utils;

import com.victualler.core.common.annotation.FieldNotNull;
import com.victualler.core.common.enums.ChecKDataErrorEnum;

import java.lang.reflect.Field;
import java.util.List;

public class BeanCheckNullUtil {

    /**
     * @Aouthor Guoshichang
     * @Date 14:26 on 2018/6/4.
     * @param params 非空的入参
     * @Function 仅仅适用于简单类型的参数 对复杂类型参数不适用
     */
    public static void checkSimpleDataParams(Object... params) throws Exception{
        boolean isHave = false;
        for (int i = 0; i < params.length; i++) {
            if(params[i] == null){
                throw new Exception(ChecKDataErrorEnum.NULL_ERROR.getKey()+":"+ChecKDataErrorEnum.NULL_ERROR.getValue()+" cause: 第"+(i+1)+"个入参为空!");
            }
        }
    }

    /**
     * @Aouthor Guoshichang
     * @Date 14:26 on 2018/6/4.
     * @param javaBean
     * @Function 校验对象空 若有空字段 则封装对应信息
     */
    public static void checkBeanNotNull(Object javaBean) throws Exception{
        try {
            String result=BeanCheckNullUtil.checkBeanNullValue(javaBean);
            if(result!=null){
                throw  new Exception(ChecKDataErrorEnum.NULL_ERROR.getKey()+":"+ChecKDataErrorEnum.NULL_ERROR.getValue()+" cause: "+result);
            }
        } catch (Exception e) {
            throw new Exception(e);
        }
    }


    /**
     * @Aouthor Guoshichang
     * @Date 14:52 on 2018/6/4.
     * @Function 校验javaBean中的必填字段非空 仅支持List内循环判断 map不判断
     * @return 若有非空校验出问题 , 则反馈对应字段信息, 都校验通过 反馈null
     */
    public static String checkBeanNullValue(Object javaBean) throws Exception {

        //防止本身传空或者为List;
        if(javaBean == null){
            return "javaBean null";
        }else if(javaBean.getClass().getName().endsWith("List")){
            return checkList(javaBean,null,(List)javaBean);
        }else if(javaBean.getClass().getName().endsWith("Map")){
            return null;
        }

        //否则
        Field[] fields = javaBean.getClass().getDeclaredFields();
        String nullField = null;
        for (Field field : fields) {
            field.setAccessible(true);
            FieldNotNull fieldNotNullAnno = field.getDeclaredAnnotation(FieldNotNull.class);
            //如果配置了必填注解
            if(fieldNotNullAnno != null){
                //开始校验
                Object  value =field.get(javaBean);
                if(value == null){
                    nullField = javaBean.getClass().getName() +":["+field.getName()+"]";
                    break;
                }else{
                    //如果是List 则循环校验
                    if(field.getType().getSimpleName().endsWith("List")){
                        List listObject = (List)(field.get(javaBean));
                        //校验List
                        String result = checkList(javaBean,field,listObject);
                        if(result!=null){
                            nullField = result;
                            break;
                        }
                    }
                    //非基础类型 递归Bean校验
                    else if(!(field.getType().getName().startsWith("java.util") || field.getType().getName().startsWith("java.math") || field.getType().getName().startsWith("java.lang"))){
                        //递归校验
                        String result = checkBeanNullValue(value);
                        if(result!=null){
                            nullField = result;
                            break;
                        }
                    }
                }
            }
        }
        return nullField ;
    }


    /**
     * @Aouthor Guoshichang
     * @Date 15:28 on 2018/6/4.
     * @param javaBean
     * @param field
     * @param listObject
     * @Function
     */
    private static String checkList(Object javaBean,Field field,List listObject) throws Exception {
        String fieldName  = field == null ? "":":["+field.getName()+"]";
        //自身非空校验
        if(listObject  == null){
            return javaBean.getClass().getName();
        }else if(listObject.size() == 0){
            FieldNotNull fieldNotNull= field.getDeclaredAnnotation(FieldNotNull.class);
            if(fieldNotNull !=null && fieldNotNull.notEmpty()){
                return javaBean.getClass().getName() +fieldName+" list.size == 0";
            }else{
                return null;
            }
        }

        //对内容非空校验
        String nullField = null;
        Object object = listObject.get(0);
        //List<List> 类型时 内部List也递归 不能为空
        if(object.getClass().getName().endsWith("List")){
            for (Object obj : listObject) {
                //递归校验List
                String result = checkList(javaBean,field,(List)obj);
                if(result!=null){
                    nullField = result;
                    break;
                }
            }
        }
        //非基础类型
        else if(!(object.getClass().getName().startsWith("java.util") || object.getClass().getName().startsWith("java.math") || object.getClass().getName().startsWith("java.lang"))){
            for (Object obj : listObject) {
                //递归校验
                String result = checkBeanNullValue(obj);
                if(result!=null){
                    nullField = result;
                    break;
                }
            }
        }
        //反馈
        return nullField;
    }

}

